Embla Carousel
Extensible bare bone carousels for the web. Build awesome carousels by extending them with your own CSS and JavaScript. Embla Carousel is dependency free and 100% open source.
TRY DEMO
options
·
api
·
events
Installation
NPM
npm install embla-carousel
QuickStart
HTML
<div class="embla">
<div class="embla__container">
<div class="embla__slide">
Slide 1
</div>
<div class="embla__slide">
Slide 2
</div>
<div class="embla__slide">
Slide 3
</div>
<div class="embla__slide">
Slide 4
</div>
</div>
</div>
CSS
.embla {
overflow: hidden;
}
.embla__container {
display: flex;
}
.embla__slide {
position: relative;
flex: 0 0 100%;
}
JavaScript
import EmblaCarousel from 'embla-carousel'
const emblaNode = document.querySelector('.embla')
const options = { loop: true }
const embla = EmblaCarousel(emblaNode, options)
Options
Configure Embla by passing an options object as the second argument. Default values are:
const embla = EmblaCarousel(emblaNode, {
align: 'center',
containerSelector: '*',
slidesToScroll: 1,
containScroll: false,
draggable: true,
dragFree: false,
loop: false,
speed: 10,
startIndex: 0,
selectedClass: 'is-selected',
draggableClass: 'is-draggable',
draggingClass: 'is-dragging',
})
align
Align the slides relative to the carousel viewport.
This option aligns the slides relative to the carousel viewport. Instead of using one of the predefined alignments
start
,
center
and
end
, you can provide a number to align the slides. For example, if you pass
0.2
, slides will be aligned 20% from the viewport start edge. Note that slide alignments will be overrided for slides at the start and end when used together with
containScroll
,
that prevents excessive scrolling at the beginning or end.
Type:
string
| number
Allowed values:
start
center
end
number
Default value:
center
Usage
const options = { align: 'start' }
const embla = EmblaCarousel(emblaNode, options)
containerSelector
Target the slide container with a query selector.
This option allows for the use of a custom query selector to match the container that holds the slides. If no value is provided Embla will match any immediate html tag. All immediate children of this container will be treated as slides.
Type:
string
Allowed values:
any
Default value:
*
Usage
const options = { containerSelector: '.my-container-selector' }
const embla = EmblaCarousel(emblaNode, options)
<div class="embla">
<div class="my-container-selector">
...slides
</div>
</div>
slidesToScroll
Scroll past the given number of slides.
This option groups slides together. Drag interactions, dot navigation, and previous/next buttons are mapped to group slides into the given number. For example, if the option is set to 2
, every two slides will be treated as a single slide.
Type:
number
Allowed values:
any
Default value:
1
Usage
const options = { slidesToScroll: 2 }
const embla = EmblaCarousel(emblaNode, options)
.embla__slide {
flex: 0 0 50%;
}
containScroll
Contain slides to the carousel viewport.
This option clears leading and trailing empty space that causes excessive scrolling. Note that this will override the chosen
alignment for slides at the beginning or the end if necessary, in order to get rid of the empty space.
Type:
boolean
Allowed values:
true
false
Default value:
false
Usage
const options = { containScroll: true }
const embla = EmblaCarousel(emblaNode, options)
draggable
Allow drag interactions to scroll the carousel.
This option enables for scrolling the carousel with mouse and touch interactions. They're are enabled by default. Use this option to turn this feature off if you have good reasons to limit the accessibility of the carousel.
Type:
boolean
Allowed values:
true
false
Default value:
true
Usage
const options = { draggable: false }
const embla = EmblaCarousel(emblaNode, options)
dragFree
Enable momentum scrolling for drag interactions.
This option enables momentum scrolling, where the carousel continues to scroll for a while after finishing the scroll gesture by releasing the mouse/touch input. The speed and duration of the continued scrolling is proportional to how vigorous the scroll gesture was.
Type:
boolean
Allowed values:
true
false
Default value:
false
Usage
const options = { dragFree: true }
const embla = EmblaCarousel(emblaNode, options)
loop
Enable infinite looping for the carousel.
This option enables infinite looping. Slides need relative positioning in order for this to work. If the carousel only has one slide it will fall back to non looping behaviour. Note that
containScroll
will be ignored if loop is enabled because the empty space is already filled with looping slides.
Type:
boolean
Allowed values:
true
false
Default value:
false
Usage
const options = { loop: true }
const embla = EmblaCarousel(emblaNode, options)
.embla__slide {
position: relative;
}
speed
Set scroll speed triggered by API navigation.
This option enables adjustment of the scroll speed when triggered by any of the API methods
scrollNext
,
scrollPrev
and
scrollTo
. Use a higher number for faster scrolling. Drag interactions are not affected by this because the speed in these cases is determined by how vigorous the drag gesture was.
Type:
number
Allowed values:
any
Default value:
10
Usage
const options = { speed: 15 }
const embla = EmblaCarousel(emblaNode, options)
startIndex
Select index of the initial scroll snap.
This option allows the selection of the initial scroll snap position. First scroll snap index starts at
0
. If slides are mapped to groups with the
slidesToScroll
option, some slides share the same scroll snap index. For example, if it's set to
2
slide one and two will be at index 0, while slide three and four will be at index 1 and so on.
Type:
number
Allowed values:
any
Default value:
0
Usage
const options = { startIndex: 3 }
const embla = EmblaCarousel(emblaNode, options)
selectedClass
Choose classname applied to the selected slides.
This option allows for a custom classname that will be applied to the selected slide. In most cases, only one slide will be selected at a time. However, when
slidesToScroll
is more than
1
and/or
containScroll
is active, slides are mapped to groups. This means that the selected class will be added to multiple slides at a time.
Type:
string
Allowed values:
any
Default value:
is-selected
Usage
const options = { selectedClass: 'my-selected-class' }
const embla = EmblaCarousel(emblaNode, options)
draggableClass
Choose classname applied to the draggable container.
This option allows for a custom classname that will be applied to the carousel container if the carousel is
draggable
. Use it to style the carousel accordingly. For example, you can show a grab cursor when a draggable carousel is hovered. If no value is provided it will fall back to
is-draggable
.
Type:
string
Allowed values:
any
Default value:
is-draggable
Usage
const options = { draggableClass: 'my-draggable-class' }
const embla = EmblaCarousel(emblaNode, options)
.my-draggable-class {
cursor: grab;
}
draggingClass
Choose classname applied to the container when dragging.
This option allows for a custom classname that will be applied to the carousel container on mousedown or touchstart, if the carousel is
draggable
. Use it to style the carousel accordingly. For example, you can show a grabbing cursor when a pointer is down. If no value is provided it will fall back to
is-dragging
.
Type:
string
Allowed values:
any
Default value:
is-dragging
Usage
const options = { draggingClass: 'my-dragging-class' }
const embla = EmblaCarousel(emblaNode, options)
.my-dragging-class {
cursor: grabbing;
}
API
Embla exposes API methods that can be used to control the carousel externally. Example usage:
embla.scrollNext()
embla.scrollTo(2)
embla.changeOptions({ loop: true })
embla.on('select', () => {
console.log(`Selected snap index is ${embla.selectedScrollSnap()}.`)
})
containerNode
Get the container node that holds the slides.
This API method returns the container node that holds the slides. If a custom selector is used by utilising the
containerSelector
option this will return the matching element, otherwise it will return the first immediate child of the Embla node passed to EmblaCarousel.
Parameters:
none
Return Type:
Node.ELEMENT_NODE
Usage
const embla = EmblaCarousel(emblaNode, options)
const emblaContainer = embla.containerNode()
slideNodes
Get the slide nodes inside the container.
This API method returns an array with the slide nodes inside the carousel container. Use this handy method if you want to manipulate the slide nodes in some way. You can also grab the length of the array to get the slide count.
Parameters:
none
Return Type:
Node.ELEMENT_NODE[]
Usage
const embla = EmblaCarousel(emblaNode, options)
const emblaSlides = embla.slideNodes()
scrollNext
Scroll to the next snap point if possible.
This API method scrolls to the next snap point if possible. If the
loop
option is disabled and the carousel is on the last snap point, this method will do nothing. When loop is enabled, it will always be able to scroll to the next snap point. Useful for creating a scroll next button for example.
Parameters:
none
Return Type:
undefined
Usage
const embla = EmblaCarousel(emblaNode, options)
const nextButton = emblaNode.querySelector('.embla__next')
nextButton.addEventListener('click', embla.scrollNext, false)
<button class="embla__next" type="button">
Scroll Next
</button>
scrollPrev
Scroll to the previous snap point if possible.
This API method scrolls to the previous snap point if possible. If the
loop
option is disabled and the carousel is on the first snap point, this method will do nothing. When loop is enabled, it will always be able to scroll to the previous snap point. Useful for creating a scroll previous button for example.
Parameters:
none
Return Type:
undefined
Usage
const embla = EmblaCarousel(emblaNode, options)
const prevButton = emblaNode.querySelector('.embla__prev')
prevButton.addEventListener('click', embla.scrollPrev, false)
<button class="embla__prev" type="button">
Scroll Previous
</button>
scrollTo
Scroll to a snap point by its unique index.
This API method scrolls to the snap point that matches the given index. When the
loop
option is enabled, the carousel will seek the closest way to the target. Useful for creating dot navigation together with the
scrollSnapList
method.
Parameters:
index: number
Return Type:
undefined
Usage
const embla = EmblaCarousel(emblaNode, options)
const rewindButton = emblaNode.querySelector('.embla__rewind')
rewindButton.addEventListener('click', () => embla.scrollTo(0), false)
<button class="embla__rewind" type="button">
Rewind
</button>
scrollToProgress
Scroll the carousel by to given location.
This API method allows users to manipulate the current
scrollProgress
from 0 to 1 by directly setting it. For example, assuming that the carousel is positioned on the first snap point,
0.5
will scroll the carousel half of its scrollable length. Scroll to target is smooth. The second parameter allows for snapping the carousel to the closest snap point based on the target scroll progress (note that this will alter the desired progress a bit in order to snap it).
Parameters:
progress: number
snap: boolean
Return Type:
undefined
Usage
const embla = EmblaCarousel(emblaNode, options)
embla.scrollToProgress(0.5)
scrollBy
Scroll the carousel by the given amount.
This API method allows users to manipulate the current
scrollProgress
from 0 to 1 by either adding to it or subtracting from it. For example, assuming that the carousel is positioned on the first snap point,
0.5
will scroll the carousel half of its scrollable length. Scroll to target is smooth. The second parameter allows for snapping the carousel to the closest snap point based on the target scroll progress (note that this will alter the desired progress a bit in order to snap it).
Parameters:
progress: number
snap: boolean
Return Type:
undefined
Usage
const embla = EmblaCarousel(emblaNode, options)
embla.scrollBy(0.5)
canScrollPrev
Check the possiblity to scroll to a previous snap point.
This API method returns a boolean that indicates if the carousel can scroll to a previous snap point from its current position. Note that if the
loop
option is enabled it will always return true. For example, it can be used to disable or enable a scroll to previous button.
Parameters:
none
Return Type:
boolean
Usage
const embla = EmblaCarousel(emblaNode, options)
const prevButton = emblaNode.querySelector('.embla__prev')
const togglePrevButtonEnabled = () => {
if (embla.canScrollPrev()) {
prevButton.removeAttribute('disabled')
} else {
prevButton.setAttribute('disabled', 'disabled')
}
}
embla.on('init', togglePrevButtonEnabled)
embla.on('select', togglePrevButtonEnabled)
<button class="embla__prev" type="button">
Scroll Previous
</button>
canScrollNext
Check the possiblity to scroll to a next snap point.
This API method returns a boolean that indicates if the carousel can scroll to a next snap point from its current position. Note that if the
loop
option is enabled it will always return true. For example, it can be used to disable or enable a scroll to next button.
Parameters:
none
Return Type:
boolean
Usage
const embla = EmblaCarousel(emblaNode, options)
const nextButton = emblaNode.querySelector('.embla__next')
const toggleNextButtonEnabled = () => {
if (embla.canScrollNext()) {
nextButton.removeAttribute('disabled')
} else {
nextButton.setAttribute('disabled', 'disabled')
}
}
embla.on('init', toggleNextButtonEnabled)
embla.on('select', toggleNextButtonEnabled)
<button class="embla__next" type="button">
Scroll Next
</button>
selectedScrollSnap
Get the index of the selected snap point.
This API method returns the index of the current selected snap point. If the
slidesToScroll
option is more than
1
some slides will be grouped together and share the same index. For example, when it's set to
2
, every two slides will share the same index. In this case, slide
1
and
2
will share index
0
and slide
3
and
4
will share index
1
and so on.
Parameters:
none
Return Type:
number
Usage
const embla = EmblaCarousel(emblaNode, options)
embla.on('select', () => {
const currentSnapIndex = embla.selectedScrollSnap()
alert(`Selected index has changed to ${currentSnapIndex}.`)
})
previousScrollSnap
Get the index of the previous snap point.
This API method returns the index of the previously selected snap point. If the
slidesToScroll
option is more than
1
some slides will be grouped together and share the same index. For example, when it's set to
2
, every two slides will share the same index. In this case, slide
1
and
2
will share index
0
and slide
3
and
4
will share index
1
and so on.
Parameters:
none
Return Type:
number
Usage
const embla = EmblaCarousel(emblaNode, options)
embla.on('select', () => {
const previousSnapIndex = embla.previousScrollSnap()
alert(`Previously selected index was ${previousSnapIndex}.`)
})
scrollSnapList
Get an array of all scroll snap points.
This API method returns an array containing all the carousel snap points. Each snap point comes with its
slideNodes
and
slideIndexes
. For example, it's useful for getting the snap point count or creating a dot navigation together with the
scrollTo
method.
Parameters:
none
Return Type:
scrollSnap[]
Usage
const embla = EmblaCarousel(emblaNode, options)
const scrollSnaps = embla.scrollSnapList()
const slidesInFirstScrollSnap = scrollSnaps[0].slideNodes
const indexesInFirstScrollSnap = scrollSnaps[0].slideIndexes
scrollProgress
Check how far the carousel has scrolled.
This API method returns how far the carousel has scrolled from
0
at the beginning to
1
at the end. For example, it's useful for creating a progress bar together with the
scroll
event. When invoking
scrollProgress
without the target parameter, the carousel returns the scroll progress of its current location. However, if you want to grab the target scroll progress the target parameter has to be
true
.
Parameters:
target: boolean
Return Type:
number
Usage
const embla = EmblaCarousel(emblaNode, options)
embla.on('scroll', () => {
const scrollPercentage = embla.scrollProgress() * 100
console.log(`The carousel has scrolled ${scrollPercentage}%.`)
})
clickAllowed
Check if interaction was a static click.
This API method returns if the user interaction was a click. For mouse events Embla will return true
if a drag interaction in any direction didn't occur before the mouse was released. Touch events also require the carousel to not be in a scrolling state in order to accept the click.
Parameters:
none
Return Type:
boolean
Usage
const embla = EmblaCarousel(emblaNode, options)
const emblaSlides = embla.slideNodes()
const alertClickedSlide = index => {
return () => {
if (embla.clickAllowed()) {
alert(`Slide with index ${index} was clicked.`)
}
}
}
emblaSlides.forEach((slide, index) => {
const alertClickedSlideIndex = alertClickedSlide(index)
slide.addEventListener('click', alertClickedSlideIndex, false)
})
changeOptions
Change the carousel options after initialization.
This API method allows for changing the carousel options after it has been initialized. Useful for changing the carousel setup depending on different screen sizes. Note that this will stop the carousel if it's in motion when change options is called, and initialize the carousel from scratch.
Return Type:
undefined
Usage
const embla = EmblaCarousel(emblaNode, options)
embla.changeOptions({ loop: true })
destroy
Destroy a carousel instance permanently.
This API method is a one way operation and destroys a carousel instance. All applied styles to DOM nodes and any event listeners will be removed. Remember to remove any external event listeners if you've used the API to create prev/next and/or dot navigation for the carousel.
Parameters:
none
Return Type:
undefined
Usage
const embla = EmblaCarousel(emblaNode, options)
embla.destroy()
on
Subscribe to an Embla specific event with a callback.
This API method enables the use of event listeners by attaching them to any of the Embla specific
events
. For example, it's useful for changing styles whenever a new target snap point has been selected or when the carousel is scrolling. Use it together with the
off
method to remove added event listeners without destroying the carousel. However, when the
destroy
method is invoked, any added event listeners will be destroyed.
Return Type:
undefined
Usage
const embla = EmblaCarousel(emblaNode, options)
const onInitCallback = () => {
console.log('The carousel is ready to rock.')
}
embla.on('init', onInitCallback)
off
Unsubscribe from an Embla specific event.
This API method enables the removal of event listeners attached to Embla specific
events
. It's useful for removing added event listeners without destroying the carousel. Note that you don't have to remove event listeners added using the
on
method when invoking
destroy
, because it will destroy all added event listeners for you.
Return Type:
undefined
Usage
const embla = EmblaCarousel(emblaNode, options)
const logIndex = () => {
const selectedIndex = embla.selectedScrollSnap()
console.log(`Selected index has changed to ${selectedIndex}.`)
}
const addLogIndexListener = () => embla.on('select', logIndex)
const removeLogIndexListener = () => embla.off('select', logIndex)
Events
Embla exposes custom events that can be hooked on to. Example usage:
embla.on('select', () => {
console.log(`Selected snap index is ${embla.selectedScrollSnap()}.`)
})
embla.on('scroll', () => {
console.log(`Scroll progress is ${embla.scrollProgress()}.`)
})
init
Fire a callback when the carousel mounts.
This event fires the given callback when the carousel has initialised and its
API
is ready to use. Note that the init event only fires once upon the first initialisation and won't trigger when invoking
changeOptions
or similar.
Usage
const embla = EmblaCarousel(emblaNode, options)
const onInitCallback = () => {
console.log('The carousel is ready to rock.')
})
embla.on('init', onInitCallback)
destroy
Fire a callback when the carousel is destroyed.
Under construction...
Usage
const embla = EmblaCarousel(emblaNode, options)
select
Fire a callback when selected scroll snap changes.
Under construction...
Usage
const embla = EmblaCarousel(emblaNode, options)
scroll
Fire a callback when the carousel is scrolling.
Under construction...
Usage
const embla = EmblaCarousel(emblaNode, options)
embla.on('scroll', () => {
const scrollPercentage = embla.scrollProgress() * 100
console.log(`The carousel has scrolled ${scrollPercentage}%.`)
})
settle
Fire a callback when the carousel has settled.
Under construction...
Usage
const embla = EmblaCarousel(emblaNode, options)
embla.on('settle', () => {
console.log(`The carousel has stopped scrolling.`)
})
resize
Fire a callback when the carousel has resized.
Under construction...
Usage
const embla = EmblaCarousel(emblaNode, options)
dragStart
Under construction...
Under construction...
Usage
const embla = EmblaCarousel(emblaNode, options)
dragEnd
Under construction...
Under construction...
Usage
const embla = EmblaCarousel(emblaNode, options)
CodeSandbox
Get started instantly with one of the CodeSandboxes below.
Basic Setup
- With Previous, Next & Dot buttons.
Autoplay
- Example of how to setup Autoplay.
Browser Support
Embla has been tested in the browsers listed below. Special thanks goes to
BrowserStack.
IE - 11
Edge - Latest 2 versions
Chrome - Latest 2 versions
Firefox - Latest 2 versions
Safari - Latest 2 versions
Open Source
Copyright © 2019-present, David Cetinkaya.
Embla is MIT licensed 💖
· · ·